package com.gframework.mybatis.dao.mybatis.plugins;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;

/**
 * 可以包含有多个 {@link ObjectWrapper} 的 ObjectWrapper对象.<br>
 * 但是仅仅只能用于查询操作，不支持设置操作。
 * <br>
 * <strong>本类是线程不安全的</strong>
 * 
 * @since 1.0.0
 * @author Ghwolf
 */
public class MultipartGetterObjectWrapper implements ObjectWrapper {

	/**
	 * 存储所有的ObjectWrapper对象
	 */
	private List<ObjectWrapper> objectWrappers;

	public MultipartGetterObjectWrapper(ObjectWrapper... objectWrappers) {
		this.objectWrappers = new ArrayList<>();
		if (objectWrappers != null && objectWrappers.length > 0) {
			Collections.addAll(this.objectWrappers, objectWrappers);
		}
	}

	public MultipartGetterObjectWrapper(List<ObjectWrapper> objectWrappers) {
		this.objectWrappers = objectWrappers;
	}

	/**
	 * 添加一个新的ObjectWrapper.<br>
	 * <strong>本类是线程不安全的，因此在执行此方法时，请不要执行其他方法</strong>
	 * 
	 * @param objectWrapper ObjectWrapper类对象
	 */
	public void addObjectWrapper(ObjectWrapper objectWrapper) {
		this.objectWrappers.add(objectWrapper);
	}

	@Override
	public Object get(PropertyTokenizer prop) {
		for (ObjectWrapper o : this.objectWrappers) {
			Object v = o.get(prop);
			if (v != null) return v;
		}
		return null;
	}

	@Override
	public String findProperty(String name, boolean useCamelCaseMapping) {
		for (ObjectWrapper o : this.objectWrappers) {
			String v = o.findProperty(name, useCamelCaseMapping);
			if (v != null) return v;
		}
		return null;
	}

	@Override
	public String[] getGetterNames() {
		List<String> list = new ArrayList<>();
		for (ObjectWrapper o : this.objectWrappers) {
			String[] arr = o.getGetterNames();
			if (arr != null && arr.length != 0) {
				Collections.addAll(list, arr);
			}
		}
		return list.toArray(new String[list.size()]);
	}

	@Override
	public Class<?> getGetterType(String name) {
		for (ObjectWrapper o : this.objectWrappers) {
			Class<?> v = o.getGetterType(name);
			if (v != null) return v;
		}
		return null;
	}

	@Override
	public boolean hasGetter(String name) {
		for (ObjectWrapper o : this.objectWrappers) {
			boolean v = o.hasGetter(name);
			if (v) return v;
		}
		return false;
	}

	
	@Override
	public String[] getSetterNames() {
		return ArrayUtils.EMPTY_STRING_ARRAY;
	}

	@Override
	public Class<?> getSetterType(String name) {
		return null;
	}

	@Override
	public boolean hasSetter(String name) {
		return false;
	}

	@Override
	public void set(PropertyTokenizer prop, Object value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean isCollection() {
		return false;
	}

	@Override
	public void add(Object element) {
		throw new UnsupportedOperationException();
	}

	@Override
	public <E> void addAll(List<E> element) {
		throw new UnsupportedOperationException();

	}

}
